home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
IRIS Performer 2.2 Friends Demo
/
SGI IRIS Performer 2.2 Friends Demo.iso
/
friends
/
openworlds
/
tix
/
ComboBox.tcl
< prev
next >
Wrap
Text File
|
1997-11-22
|
25KB
|
1,054 lines
# tixCombobox --
#
# A combobox widget is basically a listbox widget with an entry
# widget.
#
# Subwidgets
#
# button, cross, entry, listbox, shell, slistbox, tick
#
# Item shown in the entry:
# By default it will be the first item inserted into the list.
# This can be changed by "config -value" or "pick" a different
# value.
#
# Widget Commands
# align -- align the combobox to either right or left
# insert -- insert into the listbox
# pick -- select a different item in the list to show in the entry
tixWidgetClass tixComboBox {
-classname TixComboBox
-superclass tixLabelWidget
-method {
addhistory align appendhistory invoke insert pick popdown
}
-flag {
-anchor -arrowbitmap -browsecmd -command -crossbitmap
-disablecallback -disabledforeground -dropdown -editable
-fancy -grab -histlimit -historylimit -history -listcmd -listwidth
-prunehistory -selection -selectmode -state -tickbitmap -validatecmd
-value -variable
}
-static {
-fancy
}
-forcecall {
-variable -selectmode -state
}
-configspec {
{-arrowbitmap arrowBitmap ArrowBitmap [tix getbitmap cbxarrow]}
{-anchor anchor Anchor w}
{-browsecmd browseCmd BrowseCmd {}}
{-command command Command {}}
{-crossbitmap crossBitmap CrossBitmap [tix getbitmap cross]}
{-disablecallback disableCallback DisableCallback false tixVerifyBoolean}
{-disabledforeground disabledForeground DisabledForeground #606060}
{-dropdown dropDown DropDown true tixVerifyBoolean}
{-editable editable Editable false tixVerifyBoolean}
{-fancy fancy Fancy false tixVerifyBoolean}
{-grab grab Grab global}
{-listcmd listCmd ListCmd {}}
{-listwidth listWidth ListWidth {}}
{-historylimit historyLimit HistoryLimit {}}
{-history history History false tixVerifyBoolean}
{-prunehistory pruneHistory PruneHistory true tixVerifyBoolean}
{-selectmode selectMode SelectMode browse}
{-selection selection Selection {}}
{-state state State normal}
{-validatecmd validateCmd ValidateCmd {}}
{-value value Value ""}
{-variable variable Variable {}}
{-tickbitmap tickBitmap TickBitmap [tix getbitmap tick]}
}
-alias {
{-histlimit -historylimit}
}
-default {
{*Entry.relief sunken}
{*TixScrolledListBox.scrollbar auto}
{*Listbox.exportSelection false}
{*Listbox.takeFocus false}
{*shell.borderWidth 2}
{*shell.relief raised}
{*shell.cursor arrow}
{*Button.anchor c}
{*Button.borderWidth 1}
{*Button.highlightThickness 0}
{*Button.padX 0}
{*Button.padY 0}
{*tick.width 18}
{*tick.height 18}
{*cross.width 18}
{*cross.height 18}
{*arrow.anchor c}
{*arrow.width 15}
{*arrow.height 18}
{*Entry.background #c3c3c3}
{*Label.font -Adobe-Helvetica-Bold-R-Normal--*-120-*}
}
}
proc tixComboBox::InitWidgetRec {w} {
upvar #0 $w data
tixChainMethod $w InitWidgetRec
set data(popped) 0
set data(curIndex) {}
set data(fakeBrowse) 0
set data(varInited) 0
if {$data(-history)} {
set data(-editable) 1
}
}
proc tixComboBox::ConstructFramedWidget {w frame} {
upvar #0 $w data
tixChainMethod $w ConstructFramedWidget $frame
if {$data(-dropdown)} {
tixComboBox::ConstructEntryFrame $w $frame
tixComboBox::ConstructListShell $w
} else {
set f1 [frame $frame.f1]
set f2 [frame $frame.f2]
tixComboBox::ConstructEntryFrame $w $f1
tixComboBox::ConstructListFrame $w $f2
pack $f1 -side top -pady 2 -fill x
pack $f2 -side top -pady 2 -fill both -expand yes
}
}
proc tixComboBox::ConstructEntryFrame {w frame} {
upvar #0 $w data
# (1) The entry
#
set data(w:entry) [entry $frame.entry -textvariable $w::combo]
global $w::combo
trace variable $w::combo w "tixComboBox::TraceEntryVar $w"
if {!$data(-editable)} {
set bg [$w cget -bg]
$data(w:entry) config -bg $bg -state disabled -takefocus 1
}
# This is used during "config-state"
#
set data(entryfg) [$data(w:entry) cget -fg]
# (2) The dropdown button, not necessary when not in dropdown mode
#
set data(w:arrow) [button $frame.arrow -bitmap $data(-arrowbitmap)]
if {!$data(-dropdown)} {
set xframe [frame $frame.xframe -width 19]
}
# (3) The fancy tick and cross buttons
#
if {$data(-fancy)} {
if {$data(-editable)} {
set data(w:cross) [button $frame.cross -bitmap $data(-crossbitmap)]
set data(w:tick) [button $frame.tick -bitmap $data(-tickbitmap)]
pack $frame.cross -side left -padx 1
pack $frame.tick -side left -padx 1
} else {
set data(w:tick) [button $frame.tick -bitmap $data(-tickbitmap)]
pack $frame.tick -side left -padx 1
}
}
if {$data(-dropdown)} {
pack $data(w:arrow) -side right -padx 1
} else {
pack $xframe -side right -padx 1
}
pack $frame.entry -side right -fill x -expand yes -padx 1
}
proc tixComboBox::ConstructListShell {w} {
upvar #0 $w data
# Create the shell and the list
#------------------------------
set data(w:shell) [toplevel $w.shell -bd 2 -relief raised]
wm overrideredirect $data(w:shell) 1
wm withdraw $data(w:shell)
set data(w:slistbox) [tixScrolledListBox $data(w:shell).slistbox \
-anchor $data(-anchor) \
-options {listbox.selectMode "browse"}]
set data(w:listbox) [$data(w:slistbox) subwidget listbox]
pack $data(w:slistbox) -expand yes -fill both
}
proc tixComboBox::ConstructListFrame {w frame} {
upvar #0 $w data
set data(w:slistbox) [tixScrolledListBox $frame.slistbox \
-anchor $data(-anchor)]
set data(w:listbox) [$data(w:slistbox) subwidget listbox]
pack $data(w:slistbox) -expand yes -fill both
}
bind TixComboEntry <Up> {
tixComboBox::EntDirKey [tixGetMegaWidget %W] up
tixComboBox::LbBrowse [tixGetMegaWidget %W]
}
bind TixComboEntry <Down> {
tixComboBox::EntDirKey [tixGetMegaWidget %W] down
tixComboBox::LbBrowse [tixGetMegaWidget %W]
}
bind TixComboEntry <Prior> {
tixComboBox::EntDirKey [tixGetMegaWidget %W] pageup
}
bind TixComboEntry <Next> {
tixComboBox::EntDirKey [tixGetMegaWidget %W] pagedown
}
bind TixComboEntry <Double-1> {
tixComboBox::EntDouble [tixGetMegaWidget %W]
}
bind TixComboEntry <Return> {
tixComboBox::EntInvoke [tixGetMegaWidget %W] 1
}
bind TixComboEntry <1> {
tixComboBox::EntButton1 [tixGetMegaWidget %W]
}
bind TixComboEntry <KeyPress> {
tixComboBox::EntKeyPress [tixGetMegaWidget %W]
}
bind TixComboEntry <Escape> {
tixComboBox::EscKey [tixGetMegaWidget %W]
}
# The class bindings for the TixComboBox
#
bind TixComboBox <Escape> {
tixComboBox::EscKey %W
}
bind TixComboBox <1> {
if {[set %W(-dropdown)]} {
tixComboBox::CalcelXX %W
}
}
bind TixComboBox <Configure> {
tixWidgetDoWhenIdle tixComboBox::align %W
}
# Only the two "linear" detail_fields are for tabbing (moving) among
# widgets inside the same toplevel. Other detail_fields are sort
# of irrelevant
#
bind TixComboBox <FocusOut> {
if {"%d" == "NotifyNonlinear" || "%d" == "NotifyNonlinearVirtual"} {
tixComboBox::EntInvoke %W 0
}
}
bind TixComboBox <FocusIn> {
focus [%W subwidget entry]
}
proc tixComboBox::SetBindings {w} {
upvar #0 $w data
tixChainMethod $w SetBindings
# (1) Fix the bindings for the combobox
#
bindtags $w \
"$w TixComboBox [winfo toplevel $w] all"
# (2) The entry subwidget
#
tixSetMegaWidget $data(w:entry) $w
bindtags $data(w:entry) \
"$data(w:entry) Entry TixComboEntry [winfo toplevel $data(w:entry)] all"
# (3) The listbox and slistbox
#
$data(w:slistbox) config -browsecmd "tixComboBox::LbBrowse $w"
$data(w:slistbox) config -command "tixComboBox::LbCommand $w"
$data(w:listbox) config -takefocus 0
bind $data(w:listbox) <Escape> "tixComboBox::EscKey $w"
bind $data(w:slistbox) <Escape> "tixComboBox::EscKey $w"
if {$data(-dropdown)} {
bind $data(w:listbox) <ButtonRelease-1> \
"tixComboBox::ButtonHack $w; tixComboBox::LbChoose $w %x %y"
}
# (4) The buttons
#
if {$data(-dropdown)} {
$data(w:arrow) config -takefocus 0
bind $data(w:arrow) <1> "tixComboBox::BtnDown $w"
bind $data(w:arrow) <Escape> "tixComboBox::EscKey $w"
bind $data(w:root) <ButtonRelease-1> "tixComboBox::ButtonHack $w"
}
if {$data(-fancy)} {
if {$data(-editable)} {
$data(w:cross) config -command "tixComboBox::ClearEntry $w" \
-takefocus 0
}
$data(w:tick) config -command "tixComboBox::EntInvoke $w 1" -takefocus 0
}
}
#----------------------------------------------------------------------
# CONFIG OPTIONS
#----------------------------------------------------------------------
#proc tixComboBox::config-selectmode {w value} {
# upvar #0 $w data
#
# if {$data(-dropdown) && $value != "browse"} {
# puts stderr "\"$value \" selectmode not allowed for dropdown ComboBox"
# return browse
# }
#}
proc tixComboBox::config-state {w value} {
upvar #0 $w data
catch {if {[[$data(w:arrow) cget -state] == $value} {
return
}}
catch {
catch {$data(w:label) config -state $value}
catch {$data(w:arrow) config -state $value}
catch {$data(w:tick) config -state $value}
catch {$data(w:cross) config -state $value}
}
if {$value == "normal"} {
catch {
$data(w:label) config -fg [$data(w:arrow) cget -fg]
}
if {$data(-editable)} {
$data(w:entry) config -fg $data(entryfg) -state normal
} else {
$data(w:entry) config -fg $data(entryfg)
}
$data(w:entry) config -takefocus 1
} else {
catch {
$data(w:label) config -fg [$data(w:arrow) cget -disabledforeground]
}
if {$data(-editable)} {
$data(w:entry) config -fg $data(-disabledforeground) -state disabled
} else {
$data(w:entry) config -fg $data(-disabledforeground)
}
$data(w:entry) config -takefocus 0
}
}
proc tixComboBox::config-value {w value} {
upvar #0 $w data
tixComboBox::SetValue $w $value
set data(-selection) $value
tixComboBox::ClearListboxSelection $w
}
proc tixComboBox::config-variable {w arg} {
upvar #0 $w data
if [tixVariable:ConfigVariable $w $arg] {
# The value of data(-value) is changed if tixVariable:ConfigVariable
# returns true
set data(-selection) $data(-value)
tixComboBox::SetValue $w $data(-value) 1
}
catch {
unset data(varInited)
}
set data(-variable) $arg
}
#----------------------------------------------------------------------
# WIDGET COMMANDS
#----------------------------------------------------------------------
proc tixComboBox::align {w args} {
upvar #0 $w data
if {$data(-anchor) == "e"} {
tixComboBox::EntryAlignEnd $w
}
}
proc tixComboBox::addhistory {w value} {
upvar #0 $w data
tixComboBox::insert $w 0 $value
$data(w:listbox) selection clear 0 end
if {$data(-prunehistory)} {
# Prune from the end
#
set max [$data(w:listbox) size]
if {$max <= 1} {
return
}
for {set i [expr $max -1]} {$i >= 1} {incr i -1} {
if {[$data(w:listbox) get $i] == $value} {
$data(w:listbox) delete $i
break
}
}
}
}
proc tixComboBox::appendhistory {w value} {
upvar #0 $w data
tixComboBox::insert $w end $value
$data(w:listbox) selection clear 0 end
if {$data(-prunehistory)} {
# Prune from the end
#
set max [$data(w:listbox) size]
if {$max <= 1} {
return
}
for {set i [expr $max -2]} {$i >= 0} {incr i -1} {
if {[$data(w:listbox) get $i] == $value} {
$data(w:listbox) delete $i
break
}
}
}
}
proc tixComboBox::insert {w index newitem} {
upvar #0 $w data
$data(w:listbox) insert $index $newitem
if {$data(-history) && $data(-historylimit) != {}} {
if {[$data(w:listbox) size] == $data(-historylimit)} {
$data(w:listbox) delete 0
}
}
}
proc tixComboBox::config-selection {w value} {
upvar #0 $w data
tixComboBox::SetSelection $w $value
tixComboBox::ClearListboxSelection $w
}
proc tixComboBox::pick {w index} {
upvar #0 $w data
$data(w:listbox) activate $index
$data(w:listbox) selection clear 0 end
$data(w:listbox) selection set active
$data(w:listbox) see active
set text [$data(w:listbox) get $index]
tixComboBox::SetValue $w $text
set data(curIndex) $index
}
proc tixComboBox::invoke {w} {
tixComboBox::EntInvoke $w 1
}
#----------------------------------------------------------------------
# MAINTAINING THE -VALUE
#----------------------------------------------------------------------
proc tixComboBox::SetValue {w newValue {noUpdate 0}} {
upvar #0 $w data
if {$data(-validatecmd) != {}} {
set data(-value) [eval $data(-validatecmd) [list $newValue]]
} else {
set data(-value) $newValue
}
if {! $noUpdate} {
tixVariable:UpdateVariable $w
}
if {!$data(-editable)} {
$data(w:entry) delete 0 end
$data(w:entry) insert 0 $data(-value)
}
if {!$data(-disablecallback) && $data(-command) != {}} {
if {![info exists data(varInited)]} {
eval $data(-command) [list $data(-value)]
}
}
tixSetEntry $data(w:entry) $data(-value)
set data(-selection) $data(-value)
# Clear the selection
#
$data(w:entry) selection clear
if {$data(-anchor) == "e"} {
tixComboBox::EntryAlignEnd $w
}
}
proc tixComboBox::SetSelection {w value {markSel 1}} {
upvar #0 $w data
tixSetEntry $data(w:entry) $value
set data(-selection) $value
if {$data(-selectmode) == "browse"} {
if {$markSel} {
$data(w:entry) selection range 0 end
}
} else {
tixComboBox::SetValue $w $value
}
}
proc tixComboBox::ClearListboxSelection {w} {
upvar #0 $w data
$data(w:listbox) selection clear 0 end
}
proc tixComboBox::UpdateListboxSelection {w index} {
upvar #0 $w data
$data(w:listbox) selection clear 0 end
if {$index != {}} {
$data(w:listbox) selection set $index
$data(w:listbox) selection anchor $index
}
}
#----------------------------------------------------------------------
# E V E N T B I N D I N G S
#----------------------------------------------------------------------
# The combobox issues a grab after it pops up the listbox. This procedure
# will be called if the Mouse Button 1 is released outside of the listbox,
# which means the user chooses no value.
#
# In this case, just pop down the listbox and restore the combox's
# original value.
#
proc tixComboBox::BtnDown {w} {
upvar #0 $w data
if {$data(-state) == "disabled"} {
return
}
if {$data(-dropdown)} {
if {$data(popped) == 0} {
tixComboBox::PopupShell $w
set data(buttonHack) 1
} else {
tixComboBox::RestoreValue $w
tixComboBox::PopdownShell $w
catch {
unset data(buttonHack)
}
}
}
}
proc tixComboBox::CalcelXX {w} {
upvar #0 $w data
if {$data(-dropdown) && $data(popped)} {
tixComboBox::RestoreValue $w
tixComboBox::PopdownShell $w
}
}
#----------------------------------------
# Handle events inside the entry box
#----------------------------------------
proc tixComboBox::EntButton1 {w} {
upvar #0 $w data
if {$data(-state) == "disabled"} {
return
}
if {$data(-dropdown) && !$data(-editable)} {
if {$data(popped)} {
tixComboBox::RestoreValue $w
tixComboBox::PopdownShell $w
} else {
tixComboBox::PopupShell $w
}
}
}
proc tixComboBox::EntDouble {w} {
upvar #0 $w data
if {$data(-state) == "disabled"} {
return
}
if {$data(-editable)} {
$data(w:entry) select from 0
$data(w:entry) select to end
}
}
# Handles the direction keys
#
proc tixComboBox::EntDirKey {w dir} {
upvar #0 $w data
if {$data(-state) == "disabled"} {
return
}
if {$data(-dropdown) && $data(popped) == 0} {
tixComboBox::PopupShell $w
}
if {[$data(w:listbox) curselection] == {}} {
if {$data(curIndex) != {}} {
set index $data(curIndex)
} else {
set index 0
}
$data(w:listbox) activate $index
$data(w:listbox) selection clear 0 end
$data(w:listbox) selection set $index
$data(w:listbox) see $index
return
}
case $dir {
"up" {
tkListboxUpDown $data(w:listbox) -1
}
"down" {
tkListboxUpDown $data(w:listbox) 1
}
"pageup" {
$data(w:listbox) yview scroll -1 pages
}
"pagedown" {
$data(w:listbox) yview scroll 1 pages
}
}
}
proc tixComboBox::EntInvoke {w forced} {
upvar #0 $w data
if {!$forced && $data(-selection) == $data(-value)} {
return
}
if {$data(-state) == "disabled"} {
return
}
if {$data(-dropdown) && $data(popped)} {
tixComboBox::PopdownShell $w
}
if {[$data(w:listbox) curselection] == {}} {
set data(curIndex) {}
} else {
set data(curIndex) [tixComboBox::LbIndex $w]
}
tixComboBox::SetValue $w [$data(w:entry) get]
$data(w:listbox) selection clear 0 end
if {$data(-history)} {
tixComboBox::addhistory $w $data(-value)
set data(curIndex) 0
}
tixComboBox::BlinkEntry $w
}
proc tixComboBox::Invoke {w} {
upvar #0 $w data
if {$data(-state) == "disabled"} {
return
}
if {$data(-dropdown) && $data(popped)} {
tixComboBox::PopdownShell $w
}
tixComboBox::BlinkEntry $w
if {$data(-history)} {
tixComboBox::addhistory $w $data(-value)
}
}
proc tixComboBox::EntKeyPress {w} {
upvar #0 $w data
if {$data(-editable)} {
tixComboBox::ClearListboxSelection $w
if {$data(-selectmode) == "browse"} {
set data(-selection) [$data(w:entry) get]
} else {
set data(-selection) [$data(w:entry) get]
tixComboBox::SetValue $w [$data(w:entry) get]
}
}
}
#----------------------------------------------------------------------
# General functions
#
#----------------------------------------------------------------------
proc tixComboBox::EscKey {w} {
upvar #0 $w data
case $data(-selectmode) {
browse {
tixSetEntry $data(w:entry) $data(-value)
set data(-selection) $data(-value)
tixComboBox::ClearListboxSelection $w
}
immediate {
tixSetEntry $data(w:entry) $data(-value)
tixComboBox::ClearListboxSelection $w
}
}
if {$data(popped)} {
tixComboBox::PopdownShell $w
}
}
# Make the entry blink when the user selects a choice
#
proc tixComboBox::BlinkEntry {w} {
upvar #0 $w data
set old_bg [$data(w:entry) cget -bg]
set old_fg [$data(w:entry) cget -fg]
$data(w:entry) config -fg $old_bg
$data(w:entry) config -bg $old_fg
if {![info exists data(entryBlacken)]} {
set data(entryBlacken) 1
after 50 tixComboBox::RestoreEntry $w [list $old_bg] [list $old_fg]
}
}
proc tixComboBox::RestoreEntry {w old_bg old_fg} {
upvar #0 $w data
if {[info exists data(w:entry)] && [winfo exists $data(w:entry)]} {
$data(w:entry) config -fg $old_fg
$data(w:entry) config -bg $old_bg
}
if [info exists data(entryBlacken)] {
unset data(entryBlacken)
}
}
#----------------------------------------
# Handle events inside the list box
#----------------------------------------
proc tixComboBox::LbIndex {w {flag {}}} {
upvar #0 $w data
set sel [lindex [$data(w:listbox) curselection] 0]
if {$sel != {}} {
return $sel
} else {
if {$flag == "emptyOK"} {
return {}
} else {
return 0
}
}
}
proc tixComboBox::LbBrowse {w} {
upvar #0 $w data
if {$data(fakeBrowse)} {
set data(fakeBrowse) 0
return
}
set index [tixComboBox::LbIndex $w emptyOK]
if {$index >= 0} {
if {[focus -lastfor $data(w:entry)] != $data(w:entry) &&
[focus -lastfor $data(w:entry)] != $data(w:listbox)} {
focus $data(w:entry)
}
set string [$data(w:listbox) get $index]
tixComboBox::SetSelection $w $string
tixComboBox::UpdateListboxSelection $w $index
if {$data(-browsecmd) != {}} {
eval $data(-browsecmd) [list [$data(w:entry) get]]
}
}
}
proc tixComboBox::LbChoose {w x y} {
upvar #0 $w data
if {$x < 0 || $x > [winfo width $data(w:listbox)] ||
$y < 0 || $y > [winfo height $data(w:listbox)]} {
tixComboBox::EscKey $w
return
}
tixComboBox::LbCommand $w
}
proc tixComboBox::LbCommand {w} {
upvar #0 $w data
set index [tixComboBox::LbIndex $w]
if {$index >= 0} {
set data(curIndex) $index
if {$data(-dropdown) == "true" && $data(popped)} {
tixComboBox::PopdownShell $w
}
tixComboBox::SetValue $w [$data(w:listbox) get $index]
}
tixComboBox::Invoke $w
set data(fakeBrowse) 1
}
#----------------------------------------------------------------------
# Internal commands
#----------------------------------------------------------------------
proc tixComboBox::ClearEntry {w} {
upvar #0 $w data
$data(w:entry) delete 0 end
}
proc tixComboBox::RestoreValue {w} {
upvar #0 $w data
tixSetEntry $data(w:entry) $data(-value)
$data(w:entry) selection clear
}
#--------------------------------------------------
# Popping up list shell
#--------------------------------------------------
# Calculating the geometry of the combo box
#
#
proc tixComboBox::PopupShell {w} {
upvar #0 $w data
if {!$data(-dropdown)} {
return
}
if {![winfo ismapped $data(w:root)]} {
return
}
if {$data(-listcmd) != {}} {
# This option allows the user to fill in the listbox on demand
#
eval $data(-listcmd)
}
# calculate the size
set y [winfo rooty $data(w:entry)]
incr y [winfo height $data(w:entry)]
incr y 3
set bd [$data(w:shell) cget -bd]
incr bd [$data(w:shell) cget -highlightthickness]
set height [expr [winfo reqheight $data(w:slistbox)] + 2*$bd]
set x1 [winfo rootx $data(w:entry)]
if {$data(-listwidth) == {}} {
set x2 [winfo rootx $data(w:arrow)]
incr x2 [winfo width $data(w:arrow)]
set width [expr "$x2 - $x1"]
} else {
set width $data(-listwidth)
set x2 [expr $x1 + $width]
}
set reqwidth [winfo reqwidth $data(w:shell)]
if {$reqwidth < $width} {
set reqwidth $width
} else {
if {$reqwidth > [expr $width *3]} {
set reqwidth [expr $width *3]
}
if {$reqwidth > [winfo vrootwidth .]} {
set reqwidth [winfo vrootwidth .]
}
}
set width $reqwidth
# If the listbox is too far right, pull it back to the left
#
set scrwidth [winfo vrootwidth .]
if {$x2 > $scrwidth} {
set x1 [expr $scrwidth - $width]
}
# If the listbox is too far left, pull it back to the right
#
if {$x1 < 0} {
set x1 0
}
# If the listbox is below bottom of screen, put it upwards
#
set scrheight [winfo vrootheight .]
set bottom [expr $y+$height]
if {$bottom > $scrheight} {
set y [expr $y-$height-[winfo height $data(w:entry)]-5]
}
# OK , popup the shell
#
wm geometry $data(w:shell) $reqwidth\x$height+$x1+$y
wm deiconify $data(w:shell)
raise $data(w:shell)
focus $data(w:entry)
set data(popped) 1
# Grab the server so that user cannot move the windows around
#
$data(rootCmd) config -cursor arrow
catch {
# We catch here because grab may fail under a lot of circumstances
# Just don't want to break the code ...
case $data(-grab) {
global {
tixPushGrab -global $data(w:root)
}
local {
tixPushGrab $data(w:root)
}
}
}
}
proc tixComboBox::popdown {w} {
tixComboBox::PopdownShell $w
}
proc tixComboBox::PopdownShell {w} {
upvar #0 $w data
if {$data(-dropdown) && $data(popped)} {
wm withdraw $data(w:shell)
$data(rootCmd) config -cursor {}
tixPopGrab
set data(popped) 0
}
}
proc tixComboBox::TraceEntryVar {w args} {
upvar #0 $w data
global $w::combo
set value [set $w::combo]
set data(-selection) $value
set i [$data(w:listbox) curselection]
if {$i != {}} {
if {[$data(w:listbox) get $i] != $value} {
$data(w:listbox) select clear 0 end
}
}
}
# Because we do a grab, the following events sequence will make things ugly:
#
# (1) Press arrow
# (2) Move mouse out of arrow button
# (3) Release mouse button
#
# The arrow button will remain depressed (how ugly!). The following code
# fixes that
#
proc tixComboBox::ButtonHack {w} {
upvar #0 $w data
if [info exists data(buttonHack)] {
catch {
tkButtonUp $data(w:arrow)
}
}
}
#----------------------------------------------------------------------
# Alignment
#----------------------------------------------------------------------
# The following two routines can emulate a "right align mode" for the
# entry in the combo box.
proc tixComboBox::EntryAlignEnd {w} {
upvar #0 $w data
$data(w:entry) xview end
}
proc tixComboBox::Destructor {w} {
upvar #0 $w data
tixUnsetMegaWidget $data(w:entry)
tixVariable:DeleteVariable $w
catch {
global $w::combo
trace vdelete $w::combo w "tixComboBox::TraceEntryVar $w"
unset $w::combo
}
# Chain this to the superclass
#
tixChainMethod $w Destructor
}